#pragma once

#include <iostream>
#include <pthread.h>
#include <vector>
#include "Sem.hpp"
#include "Mutex.hpp"

namespace My_Ringbuffer
{
    using namespace My_Sem;
    using namespace My_Mutex;

    template <class T>
    class RingBuffer
    {
    public:
        RingBuffer(int cap = 0) : _cap(cap), _p_sem(cap), _c_sem(0), _vt(cap)
        {
        }
        void Push(const T &data)
        {

            _p_sem.P();

            {
                LockGuard lockguaed(_p_mutex);
                _vt[_p_step] = data;
                _p_step++;
                _p_step %= _cap;
            }

            _c_sem.V();
        }
        void Pop(T &data)
        {
            _c_sem.P();

            {
                LockGuard lockguaed(_c_mutex);
                data = _vt[_c_step];
                _c_step++;
                _c_step %= _cap;
            }

            _p_sem.V();
        }
        ~RingBuffer()
        {
        }

    private:
        std::vector<T> _vt;
        int _cap;
        int _c_step;
        int _p_step;

        Sem _c_sem;
        Sem _p_sem;

        Mutex _c_mutex;
        Mutex _p_mutex;
    };
}

// namespace My_Ringbuffer
// {
//     using namespace My_Sem;

//     template <class T>
//     class RingBuffer
//     {
//     public:
//         RingBuffer(int cap = 0) : _cap(cap), _p_sem(cap), _c_sem(0), _vt(cap)
//         {
//         }
//         void Push(const T &data)
//         {
//             pthread_mutex_lock(&_p_mutex);

//             _p_sem.P();

//             _vt[_p_step] = data;
//             _p_step++;
//             _p_step %= _cap;

//             _c_sem.V();

//             pthread_mutex_unlock(&_p_mutex);
//         }
//         void Pop(T &data)
//         {
//             pthread_mutex_lock(&_c_mutex);

//             _c_sem.P();

//             data = _vt[_c_step];
//             _c_step++;
//             _c_step %= _cap;

//             _p_sem.V();

//             pthread_mutex_unlock(&_c_mutex);
//         }
//         ~RingBuffer()
//         {
//         }

//     private:
//         std::vector<T> _vt;
//         int _cap;
//         int _c_step;
//         int _p_step;

//         Sem _c_sem;
//         Sem _p_sem;

//         pthread_mutex_t _c_mutex;
//         pthread_mutex_t _p_mutex;
//     };
// }